/**
 *Copyright (c) 2024 watereyes
 * safetymanagement is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.hiddendanger.service.impl;

import com.google.gson.Gson;
import com.koron.common.bean.DepartmentTreeBean;
import com.koron.common.bean.SecretBean;
import com.koron.common.bean.StaffBean;
import com.koron.common.domain.DataBean;
import com.koron.common.generator.DefaultIdGenerator;
import com.koron.common.stub.Port;
import com.koron.common.web.Util;
import com.koron.hiddendanger.domain.CheckRecord;
import com.koron.hiddendanger.domain.ChecklistEntryReference;
import com.koron.hiddendanger.domain.HiddenDangerDiscovery;
import com.koron.hiddendanger.domain.ItemCheckRecord;
import com.koron.hiddendanger.mapper.CheckRecordMapper;
import com.koron.hiddendanger.mapper.ChecklistEntryReferenceMapper;
import com.koron.hiddendanger.mapper.HiddenDangerMapper;
import com.koron.hiddendanger.mapper.ItemCheckRecordMapper;
import com.koron.hiddendanger.service.api.ChecklistEntryReferenceService;
import com.koron.hiddendanger.uitls.BusinessCode;
import com.koron.risk.bean.CorpBean;
import com.koron.risk.domain.LocalCheckListEntry;
import com.koron.risk.mapper.CorpManagementMapper;
import com.koron.risk.mapper.LocalCheckListMapper;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.swan.bean.MessageBean;

import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ChecklistEntryReferenceServiceImpl implements ChecklistEntryReferenceService {


    @Value("${app.appid}")
    private String appid;

    @Value("${app.secret}")
    private String secret;

    private final static  Logger logger = LoggerFactory.getLogger(ChecklistEntryReferenceServiceImpl.class);

    @Autowired
    private Util util;

    @Override
    public MessageBean<Integer> save(StaffBean user, ChecklistEntryReference reference) {
        MessageBean<Integer> msg = new MessageBean<>();
        SessionFactory factory = new SessionFactory();
        try {
            if (StringUtils.isEmpty(reference.getCorpCode())) {
                msg.setCode(BusinessCode.CHECKRECORD_REFERENCE_EMPTY_CROPCODE.getCode());
                msg.setDescription(BusinessCode.CHECKRECORD_REFERENCE_EMPTY_CROPCODE.getDescription());
                return msg;
            }
            if (StringUtils.isEmpty(reference.getCheckRecordId())) {
                msg.setCode(BusinessCode.CHECKRECORD_REFERENCE_EMPTY_CHECKRECORDID.getCode());
                msg.setDescription(BusinessCode.CHECKRECORD_REFERENCE_EMPTY_CHECKRECORDID.getDescription());
                return msg;
            }
            if (StringUtils.isEmpty(reference.getChecklistEntryId())) {
                msg.setCode(BusinessCode.CHECKRECORD_REFERENCE_EMPTY_CHECKLISTENTRYID.getCode());
                msg.setDescription(BusinessCode.CHECKRECORD_REFERENCE_EMPTY_CHECKLISTENTRYID.getDescription());
                return msg;
            }
            CheckRecord recordEntity = factory.getMapper(CheckRecordMapper.class).queryOne(reference.getCheckRecordId());
            if (null == recordEntity) {
                msg.setCode(BusinessCode.CHECKRECORD_REFERENCE_NOT_EXISIT_CHECKRECORDID.getCode());
                msg.setDescription(BusinessCode.CHECKRECORD_REFERENCE_NOT_EXISIT_CHECKRECORDID.getDescription());
                return msg;
            }
            if (recordEntity.getSubmit() == 1 && recordEntity.getWorkflowEditState() != 1) {
                msg.setCode(BusinessCode.CHECKRECORD_IS_COMMITED.getCode());
                msg.setDescription(BusinessCode.CHECKRECORD_IS_COMMITED.getDescription());
                return msg;
            }
            reference.setCorpCode(recordEntity.getCorpCode());

            //还要再判断检查表是否存不存在

            //校验检查项的必填字段是否为空
            List<ItemCheckRecord> itemCheckRecordList = reference.getItems();
            if (null != itemCheckRecordList && itemCheckRecordList.size() > 0) {
                for (ItemCheckRecord itemCheckRecord : itemCheckRecordList) {
                    if (StringUtils.isEmpty(itemCheckRecord.getChecklistItemId())) {
                        msg.setCode(BusinessCode.CHECKRECORD_ITEMRECORD_EMPTY_CHECKLISTITEMID.getCode());
                        msg.setDescription(BusinessCode.CHECKRECORD_ITEMRECORD_EMPTY_CHECKLISTITEMID.getDescription());
                        return msg;
                    }
                    if (StringUtils.isEmpty(itemCheckRecord.getItemName())) {
                        msg.setCode(BusinessCode.CHECKRECORD_ITEMRECORD_EMPTY_ITEMNAME.getCode());
                        msg.setDescription(BusinessCode.CHECKRECORD_ITEMRECORD_EMPTY_ITEMNAME.getDescription());
                        return msg;
                    }
                    if (StringUtils.isEmpty(itemCheckRecord.getItemName())) {
                        msg.setCode(BusinessCode.CHECKRECORD_ITEMRECORD_EMPTY_ITEMINDEX.getCode());
                        msg.setDescription(BusinessCode.CHECKRECORD_ITEMRECORD_EMPTY_ITEMINDEX.getDescription());
                        return msg;
                    }
                    if (itemCheckRecord.getNormal() == null) {
                        msg.setCode(BusinessCode.CHECKRECORD_ITEMRECORD_EMPTY_NORMAL.getCode());
                        msg.setDescription(BusinessCode.CHECKRECORD_ITEMRECORD_EMPTY_NORMAL.getDescription());
                        return msg;
                    }
                }
            }
            ChecklistEntryReferenceMapper referenceMapper = factory.getMapper(ChecklistEntryReferenceMapper.class);
            ItemCheckRecordMapper itemCheckRecordMapper = factory.getMapper(ItemCheckRecordMapper.class);
            Integer value = 0;
            if (StringUtils.isEmpty(reference.getId())) {
                //新增操作
                reference.setAddTime(reference.getUpdateTime());
                reference.setAddUser(reference.getUpdateUser());
                reference.setAddUserName(reference.getUpdateUserName());
                reference.setId(DefaultIdGenerator.getInstance().generateLongId());
                if (null != itemCheckRecordList && itemCheckRecordList.size() > 0) {
                    for (ItemCheckRecord itemCheckRecord : itemCheckRecordList) {
                        itemCheckRecord.setChecklistEntryId(reference.getId());
                        itemCheckRecord.setCheckRecordId(reference.getCheckRecordId());
                        itemCheckRecord.setId(DefaultIdGenerator.getInstance().generateLongId());
                    }
                }
                value = referenceMapper.insert(reference);
                if (value > 0 && null != itemCheckRecordList && itemCheckRecordList.size() > 0) {
                    value = itemCheckRecordMapper.batchInsert(itemCheckRecordList);
                }
            } else {
                //修改操作
                ChecklistEntryReference referenceEntity = referenceMapper.queryOne(reference.getId());
                if (null == referenceEntity) {
                    msg.setCode(BusinessCode.CHECKRECORD_REFERENCE_NOT_EXISIT.getCode());
                    msg.setDescription(BusinessCode.CHECKRECORD_REFERENCE_NOT_EXISIT.getDescription());
                    return msg;
                }
                //先删除之前填写的记录
                List<ItemCheckRecord> delItems = itemCheckRecordMapper.queryItemRecordsByReferenceId(reference.getId(), null, null);
                if (null != delItems && delItems.size() >= 0) {
                    List<String> delIdList = delItems.stream().map(ItemCheckRecord::getId).collect(Collectors.toList());
                    if (null != delIdList && delIdList.size() > 0) {
                        itemCheckRecordMapper.batchDelete(delIdList);
                    }
                }
                if (null != itemCheckRecordList && itemCheckRecordList.size() > 0) {
                    for (ItemCheckRecord itemCheckRecord : itemCheckRecordList) {
                        itemCheckRecord.setChecklistEntryId(reference.getId());
                        itemCheckRecord.setCheckRecordId(reference.getCheckRecordId());
                        itemCheckRecord.setId(DefaultIdGenerator.getInstance().generateLongId());
                    }
                }
                value = referenceMapper.update(reference);
                if (value > 0 && null != itemCheckRecordList && itemCheckRecordList.size() > 0) {
                    value = itemCheckRecordMapper.batchInsert(itemCheckRecordList);
                }
            }
            if (value > 0) {
                // 保存成功后，生成对应的隐患记录
                Boolean flag = insertHiddenDangerDiscovery(factory, user, reference, recordEntity, itemCheckRecordList);
                if (!flag) {
                    factory.close(false);
                    msg.setCode(BusinessCode.FAILURE.getCode());
                    msg.setDescription("保存失败");
                    return msg;
                }
                factory.close();
                msg.setCode(BusinessCode.SUCCESS.getCode());
                msg.setDescription("保存成功");
                return msg;
            } else {
                factory.close(false);
                msg.setCode(BusinessCode.FAILURE.getCode());
                msg.setDescription("保存失败");
                return msg;
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            if (null != factory) {
                factory.close(false);
            }
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
            return msg;
        } finally {
            if (null != factory) {
                factory.close();
            }
        }
    }

    private Boolean insertHiddenDangerDiscovery(SessionFactory factory, StaffBean user, ChecklistEntryReference reference, CheckRecord recordEntity, List<ItemCheckRecord> itemCheckRecordList) {
        try {
            if (null != itemCheckRecordList && itemCheckRecordList.size() > 0) {
                List<HiddenDangerDiscovery> dangerDiscoveryList = new ArrayList<>();
                for (ItemCheckRecord record : itemCheckRecordList) {
                    // 查看检查项是否选择了否
                    if (record.getNormal() == 0) {
                        // 先判断该条检查项是否已经生成了隐患记录
                        Integer check = factory.getMapper(CheckRecordMapper.class).checkHiddenDangerDiscovery(recordEntity.getId(), record.getChecklistItemId());
                        // 如果已经生成了隐患记录，则不再新增。
                        if (check > 0) {
                            continue;
                        }
                        // 生成一条隐患记录
                        HiddenDangerDiscovery discovery = new HiddenDangerDiscovery();
                        discovery.setGridCode(reference.getGridCode());
                        discovery.setGridName(reference.getGridName());
                        // 水司
                        discovery.setCorpCode(reference.getCorpCode());
                        discovery.setCorpName(reference.getCorpName());
                        // 标准隐患
                        String manager = recordEntity.getManager();
                        discovery.setDiscovererCode(new Gson().toJson(manager.split("[,，]]")));
                        String managerName = recordEntity.getManagerName();
                        discovery.setDiscovererDepartment(new Gson().toJson(managerName.split("[,，]]")));
                        discovery.setItemCheckRecordId(record.getChecklistItemId());
                        discovery.setDescription("检查项：" + record.getItemName() + ",发现不符合要求");
                        discovery.setDiscoveryTime(recordEntity.getCheckTime());
                        discovery.setRectificationPeriod(recordEntity.getRectificationPeriod());
                        discovery.setLocation(recordEntity.getCheckLocation());
                        dangerDiscoveryList.add(discovery);
                    }
                }
                if (null != dangerDiscoveryList && dangerDiscoveryList.size() > 0) {
                    for (HiddenDangerDiscovery discovery : dangerDiscoveryList) {
                        discovery.setCheckRecordId(recordEntity.getId());
                        discovery.setId(DefaultIdGenerator.getInstance().generateLongId());
                        discovery.setCode(generateCode(factory, discovery));
                        discovery.setDerivation(1);
                        discovery.setAddUser(user.getCode());
                        discovery.setAddUserName(user.getName());
                        discovery.setSubmitterCode(user.getCode() + "_" + user.getUserid());
                        discovery.setSubmitterDepartment(user.getDepartmentCode());
                        MessageBean<?> corpMsg = util.corp(user.getCode());
                        if (corpMsg.getCode() == 0 && null != corpMsg.getData()) {
                            DepartmentTreeBean corp = (DepartmentTreeBean) corpMsg.getData();
                            discovery.setCheckUnit(corp.getDepartmentCode());
                            discovery.setCheckUnitName(corp.getName());
                        }
                        discovery.setState(7);
                        discovery.setAddTime(new Date());
                        discovery.setUpdateUser(user.getCode());
                        discovery.setUpdateUserName(user.getName());
                        discovery.setUpdateTime(discovery.getAddTime());
                    }
                    Integer value = factory.getMapper(CheckRecordMapper.class).batchInsertHiddenDangerDiscovery(dangerDiscoveryList);
                    if (value <= 0) {
                        return false;
                    }
                }
            }
            return true;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            return false;
        }
    }


    public String generateCode(SessionFactory factory, HiddenDangerDiscovery dangerDiscovery) {
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        String date = format.format(new Date());
        Integer counter = factory.getMapper(HiddenDangerMapper.class).countCode(date.substring(2, 4));
        NumberFormat nf = NumberFormat.getInstance();
        nf.setGroupingUsed(false);
        nf.setMaximumIntegerDigits(4); // 设置最大整数位数
        nf.setMinimumIntegerDigits(4); // 设置最小整数位数
        StringBuilder sb = new StringBuilder();
        sb.append("YD").append(date.substring(2, 4)).append(nf.format(counter));
        return sb.toString();
    }


    @Override
    public MessageBean<Integer> batchDelete(String checkRecordId, List<String> idList) {
        MessageBean<Integer> msg = new MessageBean<>();
        SessionFactory factory = new SessionFactory();
        try {
            if (StringUtils.isEmpty(checkRecordId)) {
                msg.setCode(BusinessCode.CHECKRECORD_EMPTY_CHANGE_DATA.getCode());
                msg.setDescription(BusinessCode.CHECKRECORD_EMPTY_CHANGE_DATA.getDescription());
                return msg;
            }
            if (null == idList && idList.size() <= 0) {
                msg.setCode(BusinessCode.CHECKRECORD_EMPTY_CHANGE_DATA.getCode());
                msg.setDescription(BusinessCode.CHECKRECORD_EMPTY_CHANGE_DATA.getDescription());
                return msg;
            }
            CheckRecord entity = factory.getMapper(CheckRecordMapper.class).queryOne(checkRecordId);
            if (null == entity) {
                msg.setCode(BusinessCode.CHECKRECORD_NOT_EXISIT.getCode());
                msg.setDescription(BusinessCode.CHECKRECORD_NOT_EXISIT.getDescription());
                return msg;
            }
            if (entity.getSubmit() == 1) {
                msg.setCode(BusinessCode.CHECKRECORD_IS_COMMITED.getCode());
                msg.setDescription(BusinessCode.CHECKRECORD_IS_COMMITED.getDescription());
                return msg;
            }
            List<String> itemIds = new ArrayList<>();
            List<ItemCheckRecord> itemList = new ArrayList<>();
            for (String id : idList) {
                List<ItemCheckRecord> itemCheckRecords = factory.getMapper(ItemCheckRecordMapper.class).queryItemRecordsByReferenceId(id, null, null);
                if (null != itemCheckRecords && itemCheckRecords.size() > 0) {
                    itemList.addAll(itemCheckRecords);
                }
            }
            factory.getMapper(ChecklistEntryReferenceMapper.class).deleteBatch(idList);
            if (!itemList.isEmpty()) {
                itemIds = itemList.stream().map(ItemCheckRecord::getId).collect(Collectors.toList());
                factory.getMapper(ItemCheckRecordMapper.class).batchDelete(itemIds);
            }
            factory.close();
            msg.setCode(BusinessCode.SUCCESS.getCode());
            msg.setDescription("删除成功");
            msg.setData(1);
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
            return msg;
        } finally {
            factory.close();
        }
    }

    @Override
    public MessageBean<ChecklistEntryReference> queryOne(String id) {
        MessageBean<ChecklistEntryReference> msg = new MessageBean<>();
        try (SessionFactory factory = new SessionFactory()) {
            if (StringUtils.isEmpty(id)) {
                msg.setCode(BusinessCode.CHECKRECORD_EMPTY_CHANGE_DATA.getCode());
                msg.setDescription(BusinessCode.CHECKRECORD_EMPTY_CHANGE_DATA.getDescription());
                return msg;
            }
            ChecklistEntryReference reference = factory.getMapper(ChecklistEntryReferenceMapper.class).queryOne(id);
            List<ItemCheckRecord> itemCheckRecordList = factory.getMapper(ItemCheckRecordMapper.class).queryItemRecordsByReferenceId(id, null, null);
            reference.setItems(itemCheckRecordList);
            getNames(reference);
            msg.setCode(BusinessCode.SUCCESS.getCode());
            msg.setDescription("查询检查记录详情成功");
            msg.setData(reference);
            factory.close();
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
            return msg;
        }
    }

    @Override
    public MessageBean<DataBean<ChecklistEntryReference>> queryByCheckRecordId(String checkRecodId, Integer start, Integer rows) {
        MessageBean<DataBean<ChecklistEntryReference>> msg = new MessageBean<>();
        try (SessionFactory factory = new SessionFactory()) {
            if (StringUtils.isEmpty(checkRecodId)) {
                msg.setCode(BusinessCode.CHECKRECORD_EMPTY_CHANGE_DATA.getCode());
                msg.setDescription(BusinessCode.CHECKRECORD_EMPTY_CHANGE_DATA.getDescription());
                return msg;
            }
            CheckRecord entity = factory.getMapper(CheckRecordMapper.class).queryOne(checkRecodId);
            if (null == entity) {
                msg.setCode(BusinessCode.CHECKRECORD_NOT_EXISIT.getCode());
                msg.setDescription(BusinessCode.CHECKRECORD_NOT_EXISIT.getDescription());
                return msg;
            }
            List<ChecklistEntryReference> referenceList = factory.getMapper(ChecklistEntryReferenceMapper.class).queryByCheckRecordId(checkRecodId, start, rows);
            Integer totalNumber = factory.getMapper(ChecklistEntryReferenceMapper.class).countByCheckRecordId(checkRecodId);
            rows = rows == null ? totalNumber : (rows <= 0 ? 1 : rows);
            Integer totalPage = (totalNumber > rows ? (totalNumber % rows == 0 ? totalNumber / rows : totalNumber / rows + 1) : 1);
            referenceList.forEach(item -> getNames(item));
            DataBean<ChecklistEntryReference> dataBean = new DataBean<>();
            dataBean.setList(referenceList);
            dataBean.setTotalNumber(totalNumber);
            dataBean.setTotalPage(totalPage);
            dataBean.setPageSize( rows);
            msg.setCode(BusinessCode.SUCCESS.getCode());
            msg.setDescription("获取检查记录列表成功");
            msg.setData(dataBean);
            factory.close();
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
            return msg;
        }
    }

    @Override
    public void getNames(ChecklistEntryReference bean) {
        if (null != bean) {
            SessionFactory factory = new SessionFactory();
            if (StringUtils.isNotEmpty(bean.getChecklistEntryId())) {
                LocalCheckListEntry checkListEntry = factory.getMapper(LocalCheckListMapper.class).queryByid("local_checklist_entry", bean.getChecklistEntryId());
                bean.setChecklistEntryName(checkListEntry == null ? null : checkListEntry.getName());
            }
            if (StringUtils.isNotEmpty(bean.getCorpCode())) {
                CorpBean corpBean = factory.getMapper(CorpManagementMapper.class).get(bean.getCorpCode());
                bean.setCorpName(corpBean == null ? null : corpBean.getCorpName());
            }
            factory.close();
        }
    }

    @Override
    public MessageBean<DataBean<ItemCheckRecord>> queryItemsByReferenceId(String referenceId, Integer start, Integer rows) {
        MessageBean<DataBean<ItemCheckRecord>> msg = new MessageBean<>();
        try (SessionFactory factory = new SessionFactory()) {
            if (StringUtils.isEmpty(referenceId)) {
                msg.setCode(BusinessCode.CHECKRECORD_EMPTY_CHANGE_DATA.getCode());
                msg.setDescription(BusinessCode.CHECKRECORD_EMPTY_CHANGE_DATA.getDescription());
                return msg;
            }
            ChecklistEntryReference entity = factory.getMapper(ChecklistEntryReferenceMapper.class).queryOne(referenceId);
            if (null == entity) {
                msg.setCode(BusinessCode.CHECKRECORD_REFERENCE_NOT_EXISIT.getCode());
                msg.setDescription(BusinessCode.CHECKRECORD_REFERENCE_NOT_EXISIT.getDescription());
                return msg;
            }
            List<ItemCheckRecord> list = factory.getMapper(ItemCheckRecordMapper.class).queryItemRecordsByReferenceId(referenceId, start, rows);
            Integer totalNumber = factory.getMapper(ItemCheckRecordMapper.class).countItemRecordsByReferenceId(referenceId);
            rows = rows == null ? totalNumber : (rows <= 0 ? 1 : rows);
            Integer totalPage = (totalNumber > rows ? (totalNumber % rows == 0 ? totalNumber / rows : totalNumber / rows + 1) : 1);
            DataBean<ItemCheckRecord> dataBean = new DataBean<>();
            dataBean.setList(list);
            dataBean.setTotalNumber(totalNumber);
            dataBean.setTotalPage(totalPage);
            dataBean.setPageSize(rows);
            msg.setCode(BusinessCode.SUCCESS.getCode());
            msg.setDescription("获取检查记录填写的检查项列表成功");
            msg.setData(dataBean);
            factory.close();
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
            return msg;
        }
    }

    public Port getPort() {
        SecretBean bean = new SecretBean();
        bean.setSecret(secret);
        bean.setAppid(appid);
        return new Port(bean);
    }

}
